import java.util.concurrent.CountDownLatch;
/**
 * 1、定义CountDownLatch,初始化信号数目
 * 2、调用await等待信号都执行了
 * 3、调用countDown通知该进程完成了
 * 
 * 适用场景：
 * 1、初始化的信号数目不可以更改
 * 2、将一个任务分成若干线程执行，等到所有线程执行完，再进行汇总处理
 * 
 * 总结：
 * CounDownLatch对于管理一组相关线程非常有用。上述示例代码中就形象地描述了两种使用情况。
 * 第一种是计算器为1，代表了两种状态，开关。
 * 第二种是计数器为N，代表等待N个操作完成。
 * 
 * @author 10255_000
 *
 */

public class TestCountDownLatch {
	private static final int N = 10;
	
	public static void main(String[] args) throws InterruptedException {
		CountDownLatch doneSignal = new CountDownLatch(N);//10计数器
		CountDownLatch startSignal = new CountDownLatch(1);//1个计数器

		for (int i = 1; i <= N; i++) {  
            new Thread(new Worker(i, doneSignal, startSignal)).start();
        }
		
		System.out.println("begin------------");  
        startSignal.countDown();//计数器-1
        doneSignal.await();//等待
        System.out.println("Ok");  
	}
	
	static class Worker implements Runnable {
		private final CountDownLatch doneSignal;  
        private final CountDownLatch startSignal;  
        private int beginIndex;
        
        Worker(int beginIndex, CountDownLatch doneSignal,  
                CountDownLatch startSignal) {  
            this.startSignal = startSignal;  
            this.beginIndex = beginIndex;  
            this.doneSignal = doneSignal;  
        }

		@Override
		public void run() {
			try {  
                startSignal.await(); 
                beginIndex = (beginIndex - 1) * 10 + 1;  
                for (int i = beginIndex; i < beginIndex + 10; i++) {  
                    System.out.println(i);  
                }  
            } catch (InterruptedException e) {  
                e.printStackTrace();  
            } finally {  
                doneSignal.countDown();  
            } 
			
		}
		
	}

}
